GitHub ActionsでJson fileを作成/更新する方法を確認してみた
こんにちは、CX事業本部 IoT事業部の若槻です。
今回は、GitHub ActionsでJson fileを作成および更新する実装をする機会があり、方法を探してみると何パターンか見つかったため、比較のためそれぞれ試してみました。
確認してみた
次のようなPull Request作成を行うWorkflow configで、Json fileを作成および更新してみます。
on: issues: types: - assigned jobs: create_pr: runs-on: ubuntu-latest env: REPO: ${{ github.repository }} ISSUE_NUM: ${{ github.event.issue.number }} ISSUE_TITLE: ${{ github.event.issue.title }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} steps: - name: Get open linked PR id: get_open_linked_pr run: | open_linked_pr_length=$(\ gh pr list \ --repo $REPO \ --state open \ --search "close #$ISSUE_NUM in:body" \ --json number | jq '. | length'\ ) echo "::set-output name=open_linked_pr_length::$open_linked_pr_length" - name: Check open linked pr length if: steps.get_open_linked_pr.outputs.open_linked_pr_length != 0 run: | echo "Unclosed pull request is existing." exit 1 - name: Checkout uses: actions/checkout@v3 - name: Get merged linked PR id: get_merged_linked_pr run: | merged_linked_pr_length=$(\ gh pr list \ --repo $REPO \ --state merged \ --search "close #$ISSUE_NUM in:body" \ --json number | jq '. | length'\ ) echo "::set-output name=merged_linked_pr_length::$merged_linked_pr_length" - name: Make directory if: steps.get_merged_linked_pr.outputs.merged_linked_pr_length == 0 run: | mkdir $ISSUE_NUM - name: Get current date time id: get_current_date_time run: | current_date_time=$(TZ=UTC-9 date '+%Y/%m/%dT%H:%M:%S') echo "::set-output name=current_date_time::$current_date_time" # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> # ここで .json ファイルの操作を行う # <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - name: Reopen issue if: ${{ github.event.issue.state }} == "closed" run: gh issue reopen $ISSUE_NUM - name: Define new branch name id: define_new_branch_name run: | new_branch_name=$(echo "${ISSUE_NUM}-$(TZ=UTC-9 date '+%Y%m%d')") echo "::set-output name=new_branch_name::$new_branch_name" - name: Create branch uses: EndBug/add-and-commit@v9 with: new_branch: ${{ steps.define_new_branch_name.outputs.new_branch_name }} - name: Create PR run: | gh pr create \ --head $NEW_BRANCH_NAME \ --base $BASE_BRANCH_NAME \ --title "$ISSUE_TITLE" \ --body "close #${ISSUE_NUM}" env: NEW_BRANCH_NAME: ${{ steps.define_new_branch_name.outputs.new_branch_name }} BASE_BRANCH_NAME: ${{ github.event.repository.default_branch }}
59行目あたりにjsonファイル操作処理を入れてみます。
echoコマンド
標準コマンドのecho
コマンドを使用する方法です。
この方法には次のような特徴があります。
- actionを使う必要が無く、標準コマンドだけで実現可能。
- Jsonを整形したい場合は改行コード(
\n
)やスペース()を使う必要があり、データの可視性が悪くなる。
実際にWorkflowで使用してみます。
- name: Create config.json if: steps.get_merged_linked_pr.outputs.merged_linked_pr_length == 0 run: | echo -e "{\n \"createdAt\": \"${{ env.CURRENT_DATE_TIME }}\",\n \"updatedAt\": \"${{ env.CURRENT_DATE_TIME }}\"\n}" \ > $ISSUE_NUM/config.json env: CURRENT_DATE_TIME: ${{ steps.get_current_date_time.outputs.current_date_time }}
Workflowを実行すると、Json fileを新規作成できました。
jossef/action-set-json-field action
jossef/action-set-json-field actionを使用する方法です。
この方法には次のような特徴があります。
- Json fileの新規作成のみ可能。
- ファイル内容のJsonは整形されない。
echo
コマンドと同様、改行コードやスペースを指定する必要がある。
実際にWorkflowで使用してみます。
- name: Create config.json if: steps.get_merged_linked_pr.outputs.merged_linked_pr_length == 0 uses: jsdaniell/create-json@1.1.2 with: name: config.json json: '{"createdAt":"${{ env.CURRENT_DATE_TIME }}", "updatedAt":"${{ env.CURRENT_DATE_TIME }}"}' dir: ${{ env.ISSUE_NUM }}/ env: CURRENT_DATE_TIME: ${{ steps.get_current_date_time.outputs.current_date_time }}
Workflowを実行すると、Json fileを新規作成できました。
jsdaniell/create-json action
jsdaniell/create-json actionを使用する方法です。
この方法には次のような特徴があります。
- フィールドの追加および更新が可能。
- Json fileは事前に作成されている必要がある。(ファイル内容は最低限
{}
とあれば良い) - フィールドの新規追加および更新のいずれでも、Jsonの整形が行われる。
- 操作したいフィールド毎にactionを分ける必要がある。
実際にWorkflowで使用してみます。
- name: Create config file if: steps.get_merged_linked_pr.outputs.merged_linked_pr_length == 0 run: | echo -e "{}" >> $ISSUE_NUM/config.json - name: Update createdAt config.json if: steps.get_merged_linked_pr.outputs.merged_linked_pr_length == 0 uses: jossef/action-set-json-field@v1 with: file: ${{ env.ISSUE_NUM }}/config.json field: createdAt value: ${{ steps.get_current_date_time.outputs.current_date_time }} - name: Update updatedAt config.json uses: jossef/action-set-json-field@v1 with: file: ${{ env.ISSUE_NUM }}/config.json field: updatedAt value: ${{ steps.get_current_date_time.outputs.current_date_time }}
Workflowを実行すると、Json fileへフィールドを新規追加することができました。
またJson fileが作成済みおよびフィールドが追加済みの場合、更新することができました。
所感
GitHub ActionsでJson fileを作成および更新する方法をいくつか確認してみました。
個人的には、行数は増えやすいが可読性の高くなる3つ目のjsdaniell/create-json actionが使いやすいと思いました。単一のステップでフィールドの新規追加および更新のいずれにも対応させたい場合にも、難なく対応させることができます。ただ、フィールド数が非常に多くWorkflowのパフォーマンスに影響を与えかねない場合は1つ目または2つ目の方法を検討することになると思います。
以上